package myapp.camera;

import myapp.DTO.ServiceDTO;
import myapp.EnumAndConstans.Constants;
import myapp.drawable_items.BlinkAnimation;
import myapp.drawable_items.PreviewDraw;
import myapp.googlemap.R;
import myapp.helper.OrientationHelper;
import android.hardware.Camera;
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
import android.os.Bundle;
import android.app.Activity;
import android.content.Context;
import android.content.res.Configuration;
import android.text.Html;
import android.util.DisplayMetrics;
import android.view.Display;
import android.view.Gravity;
import android.view.Menu;
import android.view.Surface;
import android.view.View;
import android.view.WindowManager;
import android.view.ViewGroup.LayoutParams;
import android.view.animation.Animation;
import android.view.animation.Animation.AnimationListener;
import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.RelativeLayout;
import android.widget.TextView;

public class InteractActivity extends Activity implements AnimationListener {

	Context context;
	Camera camera;
	private static CameraPreview preview;
	PreviewDraw myDraw;
	
	ImageView imageView_left_arrow;
	ImageView imageView_right_arrow;
	TextView textView_information_interact;
	ServiceDTO serviceItem;
	Animation animation;
	
	SensorManager sensorManager;
	float[] aValues = new float[3];
	float[] mValues = new float[3];
	float[] oldAngleValues = {0f, 0f, 0f};

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_interact);
		context = this;
		
		serviceItem =  (ServiceDTO) getIntent().getExtras().get("serviceItem");
		

		myDraw = new PreviewDraw(this);
		addContentView(myDraw, new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT));		
		myDraw.setMaxDistance(2 * OrientationHelper.CalculateDistanceBetweenTwoPoints(OrientationHelper.getCurLon(), OrientationHelper.getCurLat(), serviceItem.getLongitude(), serviceItem.getLatitude()));
		
        preview = new CameraPreview(this);
        FrameLayout frameLayout = ((FrameLayout) findViewById(R.id.interact_preview));
        frameLayout.addView(preview);
		
		imageView_left_arrow = (ImageView) findViewById(R.id.imageView_left_arrow);
		imageView_right_arrow = (ImageView) findViewById(R.id.imageView_right_arrow);
		imageView_left_arrow.setVisibility(View.INVISIBLE);
		imageView_right_arrow.setVisibility(View.INVISIBLE);
		textView_information_interact = (TextView) findViewById(R.id.textView_information_interact);
		textView_information_interact.setGravity(Gravity.CENTER);
		
		RelativeLayout relativeLayout = ((RelativeLayout) findViewById(R.id.relativeLayout_arrows));
		relativeLayout.bringToFront();
		myDraw.bringToFront();
		
		animation = new BlinkAnimation();
		animation.setDuration(2000L);
		animation.setRepeatCount(-1);
		animation.setAnimationListener(this);
		
		sensorManager = (SensorManager)getSystemService(Context.SENSOR_SERVICE);
		//updateOrientation(new float[] {0, 45, 45});
	}
	
    private void updateOrientation(float[] values) {
	    	float angle = Math.abs(values[0] - oldAngleValues[0])
	    			+ Math.abs(values[1] - oldAngleValues[1])
	    			+ Math.abs(values[2] - oldAngleValues[2]);

	    	
	    	if (angle > 5f)
	    	{
		    	oldAngleValues[0] = values[0];
		    	oldAngleValues[1] = values[1];
		    	oldAngleValues[2] = values[2];
				
		    	if (OrientationHelper.isServiceInsideView(OrientationHelper.getCurLon(),
		    			OrientationHelper.getCurLat(), 
		    			serviceItem, values[0], Constants.DEGREE_VIEW) == true) // Draw service icon if service is inside the view
		    	{
					DisplayMetrics displayMetrics = new DisplayMetrics();
					getWindowManager().getDefaultDisplay().getMetrics(displayMetrics);
					myDraw.clearItems();
					myDraw.addMovableItem(serviceItem, 
							OrientationHelper.getCurLat(),
							OrientationHelper.getCurLon(),
							displayMetrics.widthPixels/2,
							displayMetrics.heightPixels*3/4,
							values[0],
							Constants.DEGREE_VIEW);	
					myDraw.invalidate();
					imageView_left_arrow.clearAnimation();
					imageView_right_arrow.clearAnimation();
    				imageView_left_arrow.setVisibility(View.INVISIBLE);
    				imageView_right_arrow.setVisibility(View.INVISIBLE);
    				
    				double distance = OrientationHelper.CalculateDistanceBetweenTwoPoints(OrientationHelper.getCurLon(), OrientationHelper.getCurLat(), serviceItem.getLongitude(), serviceItem.getLatitude());
    				textView_information_interact.setText(Html.fromHtml(serviceItem.getName()
    						+"<br/>"+"Distance:"+String.valueOf((int)distance)+"m"
    						+"<br/>"+serviceItem.getAddress()));
		    	}
		    	else { // Draw arrow if service is outside the view
		    		if (myDraw.getItemListSize() > 0)
		    		{
		    			myDraw.clearItems();
		    			myDraw.invalidate();
		    		}
		    		textView_information_interact.setText("");
		    		double degree = 0;
		    		degree = OrientationHelper.getDegreeOrientationDeviceWithService(OrientationHelper.getCurLon(), OrientationHelper.getCurLat(), serviceItem, values[0]);
		    		if (degree < 0)
		    		{
		    			if (imageView_left_arrow.getAnimation() == null)
		    			{
		    				imageView_left_arrow.startAnimation(animation);
		    				imageView_right_arrow.clearAnimation();
		    				imageView_right_arrow.setVisibility(View.INVISIBLE);
		    				imageView_left_arrow.setVisibility(View.VISIBLE);		    				
		    			}
		    		}
		    		else {
		    			if (imageView_right_arrow.getAnimation() == null)
		    			{
		    				imageView_right_arrow.startAnimation(animation);
		    				imageView_left_arrow.clearAnimation();
		    				imageView_left_arrow.setVisibility(View.INVISIBLE);
		    				imageView_right_arrow.setVisibility(View.VISIBLE);		    				
		    			}
						
					}

		    				//image.clearAnimation();

				}
    	}
}
private final SensorEventListener sensorEventListener = new SensorEventListener() {
	public void onSensorChanged(SensorEvent event) {
		boolean flag  = false;
		
		
		//Kiem tra su thay doi cua sensor ACCELEROMETER va MAGNETIC_FIELD
		switch(event.sensor.getType()){
		  case Sensor.TYPE_ACCELEROMETER:
		   for(int i =0; i < 3; i++){
		    aValues[i] = event.values[i];
		   }
		   flag = true;
		   break;
		  case Sensor.TYPE_MAGNETIC_FIELD:
		   for(int i =0; i < 3; i++){
		    mValues[i] = event.values[i];
		   }
		   flag = true;
		   break;
		  }

		if (flag == true)
		{

		   	float[] values = new float[3];
	    	float[] R = new float[9];
	        float[] outR = new float[9];
	        
	        //Lay Rotation Matrix => R
	        boolean success = SensorManager.getRotationMatrix(R, null, aValues, mValues);
	        
	        //Thay doi he truc khi quay thiet bi di dong
	        if (success)
	        {
    	        String windoSrvc = Context.WINDOW_SERVICE;
    	        WindowManager wm = ((WindowManager) getSystemService(windoSrvc));
    	        Display display = wm.getDefaultDisplay();
    	        int rotation = display.getRotation();
    	        
    	        int x_axis = SensorManager.AXIS_X; 
    	        int y_axis = SensorManager.AXIS_Y;
    	        switch (rotation) {
    	        case (Surface.ROTATION_90): 
    	        	x_axis = SensorManager.AXIS_Y; 
    	        	y_axis = SensorManager.AXIS_MINUS_X; 
    	        	break;
    	        case (Surface.ROTATION_180): 
    	        	y_axis = SensorManager.AXIS_MINUS_Y; 
    	        	break;
    	        case (Surface.ROTATION_270): 
    	        	x_axis = SensorManager.AXIS_MINUS_Y; 
    	        	y_axis = SensorManager.AXIS_X; 
    	        	break;
    	        default: break;
    	        }

    	        SensorManager.remapCoordinateSystem(R, x_axis, y_axis, outR);
    	       
    	
//R = Rz * Rx * Ry        	        
    	        double bank1, attitude1, heading1;
  	        
    	        if (outR[7]> 0.9) { // singularity at north pole
        	        heading1 = Math.atan2(-outR[3],outR[0]);
        	        attitude1 = Math.PI/2;
        	        bank1 = 0;
        	        values[1] = (float)(attitude1/Math.PI*180);
        	        values[2] = (float)(bank1/Math.PI*180);
        	        values[0] = (float)(heading1/Math.PI*180);
    	        }
    	        else if (outR[7] < -0.9) { // singularity at south pole
    	        	heading1 = Math.atan2(-outR[3],outR[0]);
        	        attitude1 = -Math.PI/2;
        	        bank1 = 0;
        	        values[1] = (float)(attitude1/Math.PI*180);
        	        values[2] = (float)(bank1/Math.PI*180);
        	        values[0] = (float)(heading1/Math.PI*180);
    	        }
    	        else
    	        {      	    	
        	        heading1 = Math.atan2(outR[1],outR[4]);
        	        attitude1 = -Math.asin(outR[7]);
        	        bank1 = Math.atan2(outR[6],outR[8]);   	        
        	        values[0] = (float)(heading1/Math.PI*180);
        	        values[1] = (float)(attitude1/Math.PI*180);
        	        values[2] = (float)(bank1/Math.PI*180);    	    	
    	        }
    	        
    	        //Kalman Filter
    	        /*km0.update(values[0]);
    	        values[0] = (float)km0.getX();
    	        km1.update(values[1]);
    	        values[1] = (float)km1.getX();
    	        km2.update(values[2]);
    	        values[2] = (float)km2.getX();*/
    	        
    	        
    	        //Update huong cua compass & yeu cau draw lai compass
    	    	updateOrientation(values);
	        }     
		}
	}
	public void onAccuracyChanged(Sensor sensor, int accuracy) {}
};

	public void onBackPressed() {
		super.onBackPressed();
		preview.DestroyCamera();
	};
	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		// Inflate the menu; this adds items to the action bar if it is present.
		getMenuInflater().inflate(R.menu.interact_menu, menu);
		return true;
	}

	@Override
	public void onConfigurationChanged(Configuration newConfig) {
		// TODO Auto-generated method stub
		
	    int rotation = this.getWindowManager().getDefaultDisplay().getRotation();
		preview.setDegreeOrientation(rotation);
		super.onConfigurationChanged(newConfig);
	}
	
	@Override
	public void onAnimationEnd(Animation arg0) {
		// TODO Auto-generated method stub
		
	}

	@Override
	public void onAnimationRepeat(Animation animation) {
		// TODO Auto-generated method stub
		
	}

	@Override
	public void onAnimationStart(Animation animation) {
		// TODO Auto-generated method stub
		
	}
	
	@Override
	protected void onResume() {
		// TODO Auto-generated method stub
		super.onResume();
		Sensor accelerometer = sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
	    Sensor magField = sensorManager.getDefaultSensor(Sensor.TYPE_MAGNETIC_FIELD);
	    
	    sensorManager.registerListener(sensorEventListener, accelerometer, SensorManager.SENSOR_DELAY_FASTEST);
	    sensorManager.registerListener(sensorEventListener, magField, SensorManager.SENSOR_DELAY_FASTEST);

	}
	
	@Override
	protected void onStop() {
		// TODO Auto-generated method stub
		super.onStop();
		sensorManager.unregisterListener(sensorEventListener);
	}

}
